﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Configuration;
using System.Reflection;
using CNative.WebApi.Common;

namespace CNative.WebApi
{
    public class ConfigHelper
    {
        public static string ExecutablePath = "";
        public ConfigHelper(string executablePath)
        {
            ExecutablePath = executablePath;
            if (string.IsNullOrEmpty(executablePath))
                ExecutablePath = Assembly.GetEntryAssembly().Location;
        }
        static ConfigHelper()
        {
            ExecutablePath = Assembly.GetEntryAssembly().Location;
        }
        /// <summary>
        /// 读取config文件
        /// </summary>
        /// <returns></returns>
        public static System.Configuration.Configuration GetConfiguration()
        {
            //指定config文件读取
            //string file = System.Windows.Forms.Application.ExecutablePath;
            var config = ConfigurationManager.OpenExeConfiguration(ExecutablePath);
            return config;
        }
        #region ConnectionStringsConfig
        /// <summary>
        /// 依据连接串名字connectionName返回数据连接字符串 
        /// </summary>
        /// <param name="connectionName"></param>
        /// <returns></returns> 
        public string GetConnectionStringsConfig(string connectionName, string configPath = "")
        {
            var config = ConfigurationManager.OpenExeConfiguration(string.IsNullOrEmpty(configPath) ? ExecutablePath : configPath);
            string connectionString =
                config.ConnectionStrings.ConnectionStrings[connectionName].ConnectionString.ToString();
            return connectionString;
        }

        ///<summary> 
        ///更新连接字符串  
        ///</summary> 
        ///<param name="newName">连接字符串名称</param> 
        ///<param name="newConString">连接字符串内容</param> 
        ///<param name="newProviderName">数据提供程序名称</param> 
        public void UpdateConnectionStringsConfig(string newName, string newConString, string newProviderName, string configPath = "")
        {
            var config = ConfigurationManager.OpenExeConfiguration(string.IsNullOrEmpty(configPath) ? ExecutablePath : configPath);

            bool exist = false; //记录该连接串是否已经存在  
            //如果要更改的连接串已经存在  
            if (config.ConnectionStrings.ConnectionStrings[newName] != null)
            {
                exist = true;
            }
            // 如果连接串已存在，首先删除它  
            if (exist)
            {
                config.ConnectionStrings.ConnectionStrings.Remove(newName);
            }
            //新建一个连接字符串实例  
            ConnectionStringSettings mySettings =
                new ConnectionStringSettings(newName, newConString, newProviderName);
            // 将新的连接串添加到配置文件中.  
            config.ConnectionStrings.ConnectionStrings.Add(mySettings);
            // 保存对配置文件所作的更改  
            config.Save(ConfigurationSaveMode.Modified);
            // 强制重新载入配置文件的ConnectionStrings配置节  
            ConfigurationManager.RefreshSection("ConnectionStrings");
        }

        ///<summary> 
        ///删除连接字符串  
        ///</summary> 
        ///<param name="newName">连接字符串名称</param> 
        public void DeleteConnectionStringsConfig(string newName, string configPath = "")
        {
            var config = ConfigurationManager.OpenExeConfiguration(string.IsNullOrEmpty(configPath) ? ExecutablePath : configPath);

            bool exist = false; //记录该连接串是否已经存在  
            //如果要更改的连接串已经存在  
            if (config.ConnectionStrings.ConnectionStrings[newName] != null)
            {
                exist = true;
            }
            // 如果连接串已存在，首先删除它  
            if (exist)
            {
                config.ConnectionStrings.ConnectionStrings.Remove(newName);
            }
            // 保存对配置文件所作的更改  
            config.Save(ConfigurationSaveMode.Modified);
            // 强制重新载入配置文件的ConnectionStrings配置节  
            ConfigurationManager.RefreshSection("ConnectionStrings");
        }
        #endregion

        #region AppSettingsConfig
        public static string GetAppConfig(string strKey, string def = "", string configPath = "")
        {
            var config = ConfigurationManager.OpenExeConfiguration(string.IsNullOrEmpty(configPath) ? ExecutablePath : configPath);
            foreach (string key in config.AppSettings.Settings.AllKeys)
            {
                if (key == strKey)
                {
                    return config.AppSettings.Settings[strKey].Value.ToString();
                }
            }
            return def;
        }
        public static string GetAppSettings(string strKey, string def = "", string configPath = "")
        {
            try
            {
                if (!string.IsNullOrEmpty(configPath))
                {
                    var config = ConfigurationManager.OpenExeConfiguration(string.IsNullOrEmpty(configPath) ? ExecutablePath : configPath);
                    foreach (string key in config.AppSettings.Settings.AllKeys)
                    {
                        if (key == strKey)
                        {
                            return config.AppSettings.Settings[strKey].Value.ToString();
                        }
                    }
                }
                var tem = System.Configuration.ConfigurationManager.AppSettings[strKey];
                if (string.IsNullOrEmpty(tem))
                    return def;
                return tem.Trim();
            }
            catch { return def; }
        }

        ///<summary>  
        ///在*.exe.config文件中appSettings配置节增加一对键值对  
        ///</summary>  
        ///<param name="newKey"></param>  
        ///<param name="newValue"></param>  
        public static void UpdateAppConfig(string newKey, string newValue, string configPath = "")
        {
            var config = ConfigurationManager.OpenExeConfiguration(string.IsNullOrEmpty(configPath) ? ExecutablePath : configPath);
            bool exist = false;
            foreach (string key in config.AppSettings.Settings.AllKeys)
            {
                if (key == newKey)
                {
                    exist = true;
                }
            }
            if (exist)
            {
                config.AppSettings.Settings.Remove(newKey);
            }
            config.AppSettings.Settings.Add(newKey, newValue);
            config.Save(ConfigurationSaveMode.Modified);
            ConfigurationManager.RefreshSection("appSettings");
        }
        /// <summary>
        /// 在*.exe.config文件中appSettings配置节删除键值对 
        /// </summary>
        /// <param name="newKey"></param>
        public static void DeleteAppConfig(string newKey, string configPath = "")
        {
            var config = ConfigurationManager.OpenExeConfiguration(string.IsNullOrEmpty(configPath) ? ExecutablePath : configPath);
            bool exist = false;
            foreach (string key in config.AppSettings.Settings.AllKeys)
            {
                if (key == newKey)
                {
                    exist = true;
                }
            }
            if (exist)
            {
                config.AppSettings.Settings.Remove(newKey);
            }
            config.Save(ConfigurationSaveMode.Modified);
            ConfigurationManager.RefreshSection("appSettings");
        }
        #endregion

        /// <summary>
        /// 获取配置节对应集合
        /// </summary>
        /// <typeparam name="TElement"></typeparam>
        /// <param name="sectionName"></param>
        /// <param name="configPath"></param>
        /// <returns></returns>
        public static List<TElement> GetElements<TElement, TElementCollection>(string sectionName, string configPath = "")
            where TElement : ConfigurationElement, new()
            where TElementCollection : ElementCollection<TElement>
        {
            var config = ConfigurationManager.OpenExeConfiguration(string.IsNullOrEmpty(configPath) ? ExecutablePath : configPath);
            if (config == null)
                return null;
            var mySection = (ConfigSection<TElement, TElementCollection>)config.GetSection(sectionName);
            if (mySection == null)
                return null;
            return mySection.ElementCollection.Cast<TElement>().ToList();
        }
        /// <summary>
        /// 配置节更新
        /// </summary>
        /// <typeparam name="TElement"></typeparam>
        /// <typeparam name="TElementCollection"></typeparam>
        /// <param name="sectionName"></param>
        /// <param name="sce"></param>
        /// <param name="configPath"></param>
        public static void UpdateElement<TElement, TElementCollection>(string sectionName, TElement sce, string configPath = "")
            where TElement : ConfigurationElement, new()
            where TElementCollection : ElementCollection<TElement>
        {
            if (sce == null)
                return;
            var config = ConfigurationManager.OpenExeConfiguration(string.IsNullOrEmpty(configPath) ? ExecutablePath : configPath);
            if (config == null)
                return;
            var mySection = (ConfigSection<TElement,TElementCollection>)config.GetSection(sectionName);
            if (mySection == null)
                return;
            mySection.ElementCollection.Update(sce);
            config.Save(ConfigurationSaveMode.Modified);
            ConfigurationManager.RefreshSection(sectionName);
        }
        /// <summary>
        /// 配置节是否存在
        /// </summary>
        /// <typeparam name="TElement"></typeparam>
        /// <typeparam name="TElementCollection"></typeparam>
        /// <param name="sectionName"></param>
        /// <param name="keyVal"></param>
        /// <param name="configPath"></param>
        /// <returns></returns>
        public static bool ExistsElement<TElement, TElementCollection>(string sectionName, string keyVal, string configPath = "")
            where TElement : ConfigurationElement, new()
            where TElementCollection : ElementCollection<TElement>
        {
            if (string.IsNullOrEmpty(keyVal))
                return false;
            var config = ConfigurationManager.OpenExeConfiguration(string.IsNullOrEmpty(configPath) ? ExecutablePath : configPath);
            if (config == null)
                return false;
            var mySection = (ConfigSection<TElement, TElementCollection>)config.GetSection(sectionName);
            if (mySection == null)
                return false ;
            return mySection.ElementCollection.Exists(keyVal);
        }
        /// <summary>
        /// 配置节删除键值对
        /// </summary>
        /// <typeparam name="TElement"></typeparam>
        /// <typeparam name="TElementCollection"></typeparam>
        /// <param name="sectionName"></param>
        /// <param name="keyVal"></param>
        /// <param name="configPath"></param>
        public static void DeleteElement<TElement, TElementCollection>(string sectionName, string keyVal, string configPath = "")
            where TElement : ConfigurationElement, new()
            where TElementCollection : ElementCollection<TElement>
        {
            if (string.IsNullOrEmpty(keyVal))
                return;
            var config = ConfigurationManager.OpenExeConfiguration(string.IsNullOrEmpty(configPath) ? ExecutablePath : configPath);
            if (config == null)
                return;
            var mySection = (ConfigSection<TElement, TElementCollection>)config.GetSection(sectionName);
            if (mySection == null)
                return;
            mySection.ElementCollection.Delete(keyVal);
            config.Save(ConfigurationSaveMode.Modified);
            ConfigurationManager.RefreshSection(sectionName);
        }
    }

}
